package com.pinc.exam;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.StreamCorruptedException;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceActivity;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class Test_Setting extends PreferenceActivity {
	private static final int SLCT_SRC_REQ = 0;
	private static final int SLCT_QCOUNT_REQ = 1;
	private ListPreference lp_source;
	private Preference p_count;
	private CheckBoxPreference cbp_smart;
	private CheckBoxPreference cbp_rand_sel;
	private CheckBoxPreference cbp_rand_question;
	private CheckBoxPreference cbp_practice;
	private int mSource;
	private long[] mSlctIDs;
	private int mQsetSize;
	private DBClass dbHelper;
	private Question_Packet mQP;
	private Cursor mCursor;
	public static final int SRC_LIB = 0;
	public static final int SRC_GROUP = 1;
	public static final int SRC_MISSED = 2;
	public static final int SRC_ALL = 3;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.test_setting);
		addPreferencesFromResource(R.xml.test_setting);

		File file = getFileStreamPath(GParam.QUIZ_FILENAME);
		if ( file.exists())
		{
			showDialog(ID_RESTORE);
		}

		dbHelper = new DBClass(this);
		mQP = new Question_Packet();

		lp_source = (ListPreference) this.findPreference("source");
		p_count = (Preference)this.findPreference("qcount");
		cbp_rand_sel = (CheckBoxPreference)this.findPreference("rand_sel");
		cbp_rand_question = (CheckBoxPreference)this.findPreference("rand_qstn");
		cbp_smart = (CheckBoxPreference)this.findPreference("smart");
		cbp_practice = (CheckBoxPreference)this.findPreference("prac_mode");

		lp_source.setValue(null);
		lp_source.setOnPreferenceChangeListener(new OnPreferenceChangeListener(){
			public boolean onPreferenceChange(Preference preference, Object newValue) {
				String[] str_values = getResources().getStringArray(R.array.test_source);
				if ( str_values[0].compareTo((String)newValue) == 0)
				{
					Intent intent = new Intent(Test_Setting.this, Select_Questions.class);
					intent.putExtra("source", 0);
					startActivityForResult(intent, SLCT_SRC_REQ);
					p_count.setSummary("");
				}
				else if ( str_values[1].compareTo((String)newValue) == 0){
					Intent intent = new Intent(Test_Setting.this, Select_Questions.class);
					intent.putExtra("source", 1);
					startActivityForResult(intent, SLCT_SRC_REQ);
				}
				else if ( str_values[2].compareTo((String)newValue) == 0)
				{
					p_count.setEnabled(true);
					mQsetSize = dbHelper.getQuestionNoInMissedList();
					mSource = SRC_MISSED;
					mSlctIDs = new long[1];
					queryQuetsionCount();
					p_count.setSummary("");
				}
				else if ( str_values[3].compareTo((String)newValue) == 0)
				{
					p_count.setEnabled(true);
					mQsetSize = dbHelper.getQuestionNoInCategory(-1);
					mSource = SRC_ALL;
					mSlctIDs = new long[1];
					queryQuetsionCount();
					p_count.setSummary("");
				}
				((ListPreference)preference).setSummary((String)newValue);
				return true;
			}
		});

		p_count.setOnPreferenceClickListener(new OnPreferenceClickListener(){
			@Override
			public boolean onPreferenceClick(Preference preference) {
				queryQuetsionCount();
				return false;
			}
		});

		/* set upbar */
		TextView tv_title = (TextView)this.findViewById(R.id.textView_title);
		tv_title.setText(getResources().getString(R.string.str_quiz));

		Button b_back = (Button)this.findViewById(R.id.button_left);
		b_back.setVisibility(View.VISIBLE);
		b_back.setText(getResources().getString(R.string.str_back));
		b_back.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				finish();
			}
		});

		Button b_start = (Button)this.findViewById(R.id.button_right);
		b_start.setVisibility(View.VISIBLE);
		b_start.setText(getResources().getString(R.string.str_start_quiz));
		b_start.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				if (isLegal())
				{
					String by_credit = DBClass.COL_QLIB_CREDIT;
					String orderby = (cbp_rand_question.isChecked())?"RANDOM()":"_id";
					switch (mSource)
					{
					case SRC_LIB:
					{
						boolean first = true;
						String wherestr="";
						String sql;
						for ( int i = 0; i< mSlctIDs.length;i++)
						{
							if (!first)
								wherestr+=",";
							wherestr+=(" "+mSlctIDs[i]);
							first=false;
						}
						if ( cbp_smart.isChecked()) //By credit
						{
							sql = "SELECT * FROM ( SELECT * FROM " + DBClass.TABLE_NAME_QLIB + " WHERE " + DBClass.COL_QLIB_CATEGORY + " IN (" + wherestr + ") AND " + by_credit + " <= (SELECT MAX(" + by_credit + ") FROM "+DBClass.TABLE_NAME_QLIB + " WHERE _id IN (SELECT _id FROM " + DBClass.TABLE_NAME_QLIB + " WHERE " + DBClass.COL_QLIB_CATEGORY + " IN (" + wherestr + ") ORDER BY "+ by_credit + " LIMIT "+ mQP.mQstn_total +")) ORDER BY RANDOM() LIMIT " + mQP.mQstn_total + " ) ORDER BY " + orderby;
						}
						else //By random
						{
							sql = "SELECT * FROM ( SELECT * FROM " + DBClass.TABLE_NAME_QLIB + " WHERE " + DBClass.COL_QLIB_CATEGORY + " IN (" + wherestr + ") ORDER BY RANDOM() LIMIT " + mQP.mQstn_total + ") ORDER BY " + orderby;
						}
						mCursor = dbHelper.SQLQuery(sql, null);
					}
					break;
					case SRC_GROUP:
					{
						boolean first = true;
						String wherestr="";
						String sql;
						for ( int i = 0; i< mSlctIDs.length;i++)
						{
							if (!first)
								wherestr+=" UNION ";
							wherestr+=("SELECT " + DBClass.COL_GROUP_QID + " FROM " + DBClass.MY_GROUP_TABLE_PREFIX + mSlctIDs[i]);
							first=false;
						}
						if ( cbp_smart.isChecked()) //By credit
						{
							sql = "SELECT * FROM ( SELECT * FROM " + DBClass.TABLE_NAME_QLIB + " WHERE _id IN (" + wherestr + ") AND " + by_credit + " <= (SELECT MAX(" + by_credit + ") FROM " + DBClass.TABLE_NAME_QLIB + " WHERE _id IN (SELECT _id FROM " + DBClass.TABLE_NAME_QLIB + " WHERE _id IN (" + wherestr + ") ORDER BY "+ by_credit + " LIMIT "+ mQP.mQstn_total +")) ORDER BY RANDOM() LIMIT " + mQP.mQstn_total + " ) ORDER BY " + orderby;
						}
						else //By random
						{
							sql = "SELECT * FROM ( SELECT * FROM " + DBClass.TABLE_NAME_QLIB + " WHERE _id IN (" + wherestr + ") ORDER BY RANDOM() LIMIT "+ mQP.mQstn_total + ") ORDER BY " + orderby;
						}
						mCursor = dbHelper.SQLQuery(sql, null);
					}
					break;
					case SRC_MISSED:
					{
						String sql;
						if ( cbp_smart.isChecked()) //By credit
						{
							sql = "SELECT * FROM ( SELECT * FROM " + DBClass.TABLE_NAME_QLIB + " WHERE _id IN ( SELECT " + DBClass.COL_MISSED_LIST_QID + " FROM " + DBClass.TABLE_NAME_MISSED_LIST + ") AND " + by_credit + " <= ( SELECT MAX(" + by_credit + ") FROM " + DBClass.TABLE_NAME_QLIB + " WHERE _id IN (SELECT _id FROM " + DBClass.TABLE_NAME_QLIB + " WHERE _id IN ( SELECT " + DBClass.COL_MISSED_LIST_QID + " FROM " + DBClass.TABLE_NAME_MISSED_LIST + " )" + " ORDER BY "+ by_credit + " LIMIT "+ mQP.mQstn_total +")) ORDER BY RANDOM() LIMIT " + mQP.mQstn_total + ") ORDER BY " + orderby;
						}
						else //By random
						{
							sql = "SELECT * FROM ( SELECT * FROM " + DBClass.TABLE_NAME_QLIB + " WHERE _id IN ( SELECT " + DBClass.COL_MISSED_LIST_QID + " FROM " + DBClass.TABLE_NAME_MISSED_LIST + ") ORDER BY RANDOM() LIMIT " + mQP.mQstn_total + ") ORDER BY " + orderby;
						}
						mCursor = dbHelper.SQLQuery(sql, null);
					}
					break;
					case SRC_ALL:
					{
						String sql;
						if ( cbp_smart.isChecked()) //By credit
						{
							sql = "SELECT * FROM ( SELECT * FROM " + DBClass.TABLE_NAME_QLIB + " WHERE " + by_credit + " <= (SELECT MAX(" + by_credit + ") FROM " + DBClass.TABLE_NAME_QLIB + " WHERE _id IN (SELECT _id FROM " + DBClass.TABLE_NAME_QLIB + " ORDER BY "+ by_credit + " LIMIT "+ mQP.mQstn_total +")) ORDER BY RANDOM() LIMIT " + mQP.mQstn_total + ") ORDER BY " + orderby;
						}
						else //By random
						{
							sql = "SELECT * FROM ( SELECT * FROM " + DBClass.TABLE_NAME_QLIB + " ORDER BY RANDOM() LIMIT " + mQP.mQstn_total + ") ORDER BY " + orderby;
						}
						Log.v("sql=", sql);
						mCursor = dbHelper.SQLQuery(sql, null);
					}
					break;
					}
					fillPacket();
					Intent intent = new Intent(Test_Setting.this, Test_Start.class);
					intent.putExtra("packet", mQP);
					startActivity(intent);
					finish();
				}
			}
		});
	}

	private void fillPacket()
	{
		mQP.mSource = mSource;
		mQP.cur_qstn = 0;
		mQP.mPractice = cbp_practice.isChecked();
		mQP.mArr_Qid = new int[mQP.mQstn_total];
		mQP.mArr_ansPaper = new int[mQP.mQstn_total];
		mQP.mArr_answer = new boolean[mQP.mQstn_total][];
		mQP.mArr_sel = new String[mQP.mQstn_total][];
		mQP.mQuestion = new String[mQP.mQstn_total];
		mQP.mImgID = new int[mQP.mQstn_total];
		String[] s = new String[GParam.SELECT_MAX];
		if (mCursor.moveToFirst())
		{
			int i = 0;
			do{
				mQP.mArr_ansPaper[i] = 0;
				mQP.mArr_Qid[i] = mCursor.getInt(mCursor.getColumnIndex("_id"));
				mQP.mQuestion[i] = mCursor.getString(mCursor.getColumnIndex(DBClass.COL_QLIB_QUESTION));
				mQP.mImgID[i] = mCursor.getInt(mCursor.getColumnIndex(DBClass.COL_QLIB_IMAGE));
				int sel_total = mCursor.getInt(mCursor.getColumnIndex(DBClass.COL_QLIB_SEL_TOTAL));
				String orig_answer_str = mCursor.getString(mCursor.getColumnIndex(DBClass.COL_QLIB_ANS));
				s[0] = mCursor.getString(mCursor.getColumnIndex(DBClass.COL_QLIB_SEL1));
				s[1] = mCursor.getString(mCursor.getColumnIndex(DBClass.COL_QLIB_SEL2));
				s[2] = mCursor.getString(mCursor.getColumnIndex(DBClass.COL_QLIB_SEL3));
				s[3] = mCursor.getString(mCursor.getColumnIndex(DBClass.COL_QLIB_SEL4));
				s[4] = mCursor.getString(mCursor.getColumnIndex(DBClass.COL_QLIB_SEL5));
				mQP.mArr_sel[i] = new String[sel_total];
				int[] arr_tmp = new int[sel_total];
				if ( cbp_rand_sel.isChecked())
					mQP.mArr_answer[i] = rand_Sel(arr_tmp, sel_total, orig_answer_str);
				else
					mQP.mArr_answer[i] = order_Sel(arr_tmp, sel_total, orig_answer_str);
				for ( int j = 0; j< sel_total; j++)
				{
					mQP.mArr_sel[i][j] = s[arr_tmp[j]-1];
				}
				i++;
			}while(mCursor.moveToNext());
		}
		mCursor.close();
		dbHelper.mDB.close();
	}

	private static boolean[] rand_Sel(int[] arr, int count, String origAns)
	{
		boolean[] answer;
		int pool[] = {1,2,3,4,5};
		int loop = count;

		boolean[] orig_answer = AnsStr2Arr(origAns);
		answer = new boolean[orig_answer.length];

		for ( int i = 0; i < loop; i++)
		{
			int select = (int) (Math.random()*count);
			answer[i] = orig_answer[pool[select]-1];
			arr[i] = pool[select];
			for ( int j = select ; j < count-1 ; j++)
			{
				pool[j] = pool[j+1];
			}
			count--;
		}
		return answer;
	}

	private static boolean[] order_Sel(int[] arr, int count, String origAns)
	{
		for ( int i = 0; i < count; i++)
		{
			arr[i] = i+1;
		}
		return AnsStr2Arr(origAns);
	}

	public static boolean[] AnsStr2Arr(String str)
	{
		String[] ansstr = TextUtils.split(str, ",");
		boolean[] ret = new boolean[GParam.SELECT_MAX];
		for ( int i=0; i<ret.length;i++)
			ret[i] = false;
		for ( int i=0; i<ansstr.length;i++)
			ret[Integer.parseInt(ansstr[i])-1] = true;
		return ret;
	}

	private boolean isLegal()
	{
		if ( lp_source.getValue() == null || lp_source.getValue().length() == 0)
		{
			showDialog(ID_SRC);
			return false;
		}

		if ( p_count.getSummary() == null)
		{
			showDialog(ID_QNO);
			return false;
		}

		String count_str = p_count.getSummary().toString();

		if ( count_str.length() == 0)
		{
			showDialog(ID_QNO);
			return false;
		}

		int qno_input = Integer.parseInt(count_str);
		if ( qno_input <= 0 || qno_input > mQsetSize)
		{
			showDialog(ID_QNO);
			return false;
		}

		mQP.mQstn_total = qno_input;

		return true;
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		if ( requestCode == SLCT_SRC_REQ )
		{
			switch (resultCode)
			{
			case Activity.RESULT_OK:
				mSlctIDs = data.getLongArrayExtra("ids");
				mQsetSize = data.getIntExtra("size", 0);
				mSource = data.getIntExtra("source", 0);
				switch (mSource)
				{
				case SRC_GROUP:
					p_count.setEnabled(true);
					p_count.setSummary("");
					queryQuetsionCount();
					break;
				case SRC_LIB:
					p_count.setEnabled(true);
					p_count.setSummary("");
					queryQuetsionCount();
					break;
				}
				break;
			default:
				lp_source.setValue(null);
				lp_source.setSummary("");
				p_count.setSummary("");
				break;
			}
		}
		else if ( requestCode == SLCT_QCOUNT_REQ )
		{
			switch (resultCode)
			{
			case Activity.RESULT_OK:
				int count = data.getIntExtra("count", 0);
				p_count.setSummary(String.format("%d", count));
				break;
			default:
				break;
			}
		}
	}

	private void queryQuetsionCount()
	{
		Intent intent = new Intent(Test_Setting.this, QCount_Picker.class);
		intent.putExtra("bound", mQsetSize);
		startActivityForResult(intent, SLCT_QCOUNT_REQ);
	}

	private static final int ID_SRC = 0;
	private static final int ID_QNO = 1;
	private static final int ID_RESTORE = 2;
	@Override
	protected Dialog onCreateDialog(int id) {
		AlertDialog.Builder builder = new AlertDialog.Builder(this);

		switch(id)
		{
		case ID_SRC:
		{
			builder.setMessage(getResources().getString(R.string.str_select) + getResources().getString(R.string.str_question_source))
			.setPositiveButton(getResources().getString(R.string.str_ok), null);
			break;
		}
		case ID_QNO:
		{
			builder.setMessage(getResources().getString(R.string.str_select) + getResources().getString(R.string.str_quiz_question_number))
			.setPositiveButton(getResources().getString(R.string.str_ok), null);
			break;
		}
		case ID_RESTORE:
		{
			builder.setMessage(getResources().getString(R.string.str_if_restore))
			.setPositiveButton(getResources().getString(R.string.str_ok), new DialogInterface.OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
					try {
						FileInputStream fis = openFileInput(GParam.QUIZ_FILENAME);
						ObjectInputStream ois = new ObjectInputStream(fis);
						mQP = (Question_Packet) ois.readObject();
						ois.close();
						fis.close();
						Intent intent = new Intent(Test_Setting.this, Test_Start.class);
						intent.putExtra("packet", mQP);
						startActivity(intent);
						finish();
					} catch (FileNotFoundException e) {
						e.printStackTrace();
					} catch (StreamCorruptedException e) {
						e.printStackTrace();
					} catch (IOException e) {
						e.printStackTrace();
					} catch (ClassNotFoundException e) {
						e.printStackTrace();
					}
				}
			})
			.setNegativeButton(getResources().getString(R.string.str_cancel), null);
			break;
		}
		default:
			break;
		}
		return builder.create();
	}

}	
